package top.eleven.sixpence.generaterollbacksql.holder;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import top.eleven.sixpence.generaterollbacksql.annotation.Value;
import top.eleven.sixpence.generaterollbacksql.common.CommonConstant;
import top.eleven.sixpence.generaterollbacksql.common.util.StringUtils;

import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Properties;
import java.util.stream.Collectors;

/**
 * 读取配置文件并为对应对象赋值
 *
 * @author eleven
 */
public class PropertiesHolder {
    private static final Logger LOGGER = LoggerFactory.getLogger(PropertiesHolder.class);
    private static final HashMap<String, String> PROPERTIES = new HashMap<String, String>(16);

    static {
        loadProperties();
    }

    /**
     * 加载配置文件数据到map中
     */
    private static void loadProperties() {
        Properties pro = new Properties();
        InputStream is = PropertiesHolder.class.getResourceAsStream("/application.properties");
        try {
            pro.load(is);
            Iterator<Object> iterator = pro.keySet().iterator();
            while (iterator.hasNext()) {
                String key = (String) iterator.next();
                PROPERTIES.put(key, (String) pro.get(key));
            }
        } catch (Exception e) {
            LOGGER.error("load properties failed, use default properties", e);
        }
    }

    /**
     * 注入配置到对象中
     *
     * @param obj
     */
    public static void setProperties(Object obj) {
        Class<?> clazz = obj.getClass();
        List<Method> methods = Arrays.stream(clazz.getMethods()).filter(m -> m.getName().startsWith("set")).collect(Collectors.toList());
        for (Method method : methods) {
            Value valueAnnotation = method.getAnnotation(Value.class);
            if(Objects.nonNull(valueAnnotation)){
                String value = PROPERTIES.get(valueAnnotation.key());
                value = StringUtils.isNotBlank(value) ? value : valueAnnotation.defaultValue();
                try {
                    setValue(method, obj, value);
                } catch (Exception e) {
                    LOGGER.error("set {}={} failed, use default value", method.getParameters()[0], value);
                }
            }
        }
    }


    private static void setValue(Method method, Object obj,  String value) throws IllegalAccessException, InvocationTargetException {
        if (String[].class.equals(method.getParameterTypes()[0])) {
            method.invoke(obj, (Object) value.split(CommonConstant.COMMA));
        } else {
            method.invoke(obj, value);
        }
    }

}